home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / MacPerl 5.1.3 / Mac_Perl_513_src / perl5.002 / HandleSocket.cp < prev    next >
Encoding:
Text File  |  1996-07-14  |  2.7 KB  |  144 lines  |  [TEXT/MPCC]

  1. /*********************************************************************
  2. Project    :    GUSI                -    Grand Unified Socket Interface
  3. File        :    HandleSocket.cp-    Handle sockets
  4. Author    :    Matthias Neeracher <neeri@iis.ee.ethz.ch>
  5. Language    :    MPW C++
  6.  
  7. $Log: GUSIFile.cp,v $
  8. *********************************************************************/
  9.  
  10. #include "GUSI_P.h"
  11.  
  12. #include <IOCtl.h>
  13.  
  14. extern "C" int OpenHandle(Handle h, int oflag);
  15.  
  16. class HandleSocket : public Socket {
  17.     friend int OpenHandle(Handle h, int oflag);
  18. protected:
  19.     HandleSocket(Handle h, int oflag);
  20. public:
  21.     virtual int    read(void * buffer, int buflen);
  22.     virtual int write(void * buffer, int buflen);
  23.     virtual int    ioctl(unsigned int request, void *argp);
  24.     virtual long lseek(long offset, int whence);
  25.     virtual int ftruncate(long offset);
  26. private:
  27.     Handle    data;
  28.     long        pos;
  29.     Boolean    append;
  30. };
  31.  
  32. /************************ HandleSocket members ************************/
  33.  
  34. HandleSocket::HandleSocket(Handle h, int oflag)
  35.  : Socket(), data(h), pos(0)
  36. {
  37.     if (oflag & O_TRUNC)
  38.         SetHandleSize(data, 0);
  39.     append    =    (oflag & O_APPEND) != 0; 
  40. }
  41.  
  42. int HandleSocket::read(void * buffer, int buflen)
  43. {
  44.     long    length     =     buflen;
  45.     long    left        =    GetHandleSize(data)-pos;
  46.     
  47.     if (length > left)
  48.         length = left;
  49.         
  50.     if (length) {
  51.         HLock(data);
  52.         memcpy(buffer, *data+pos, length);
  53.         pos += length;
  54.         HUnlock(data);
  55.     }
  56.     
  57.     return int(length);
  58. }
  59.  
  60. int HandleSocket::write(void * buffer, int buflen)
  61. {
  62.     if (append)
  63.         pos = GetHandleSize(data);
  64.     
  65.     long size = GetHandleSize(data);
  66.     if (pos+buflen > size) {
  67.         SetHandleSize(data, pos+buflen);
  68.         while (size < pos)
  69.             (*data)[size++] = 0;
  70.     }
  71.     if (buflen) {
  72.         HLock(data);
  73.         memcpy(*data+pos, buffer, buflen);
  74.         pos += buflen;
  75.         HUnlock(data);
  76.     }
  77.     
  78.     return buflen;
  79. }
  80.  
  81. int HandleSocket::ioctl(unsigned int request, void *argp)
  82. {
  83.     switch (request) {
  84.     case FIONREAD:
  85.         *(long *) argp    = GetHandleSize(data) - pos;
  86.         
  87.         return 0;
  88.     default :
  89.         return Socket::ioctl(request, argp);
  90.     }
  91. }
  92.  
  93. long HandleSocket::lseek(long offset, int whence)
  94. {    
  95.     long newPos;
  96.     
  97.     switch (whence) {
  98.     case SEEK_CUR:
  99.         newPos = pos+offset;
  100.         break;
  101.     case SEEK_END:
  102.         newPos = GetHandleSize(data)+offset;
  103.         break;
  104.     case SEEK_SET:
  105.         newPos = offset;
  106.         break;
  107.     default:
  108.         return GUSI_error(EINVAL);
  109.     }
  110.     if (newPos < 0)
  111.         return GUSI_error(EINVAL);
  112.     else
  113.         return pos = newPos;
  114. }
  115.  
  116. int HandleSocket::ftruncate(long offset)
  117. {    
  118.     if (offset > GetHandleSize(data)) {
  119.         lseek(offset, SEEK_SET);
  120.         write(nil, 0);
  121.     } else
  122.         SetHandleSize(data, offset);
  123.     
  124.     return 0;
  125. }
  126.  
  127. int OpenHandle(Handle h, int oflag)
  128. {    
  129.     int        fd;
  130.     Socket * sock = new HandleSocket(h, oflag);
  131.     
  132.     if (sock)
  133.         if ((fd = Sockets.Install(sock)) != -1)
  134.             return fd;
  135.         else
  136.             delete sock;
  137.  
  138.     if (!errno)
  139.         return GUSI_error(ENOMEM);
  140.     else
  141.         return -1;
  142. }
  143.  
  144.